﻿using System;
using System.Collections.Generic;

namespace yacomp.os
{
    using yacomp.helpers;
    using yacomp.structs;
    public class YacompPath
    {
        internal struct_yacomp_path info;
        internal YacompStorage ref_storage;
        internal List<string> files;
        internal List<string> paths;
        internal bool root_path = false;
        public DateTime EditTime { get { return info.time_edit; } }
        public string PathName;
        public string Name;
        public string ID { get { return info.id; } }
        internal YacompPath(struct_yacomp_path path, YacompStorage storage)
        {
            info = path;
            ref_storage = storage;
            files = new List<string>();
            paths = new List<string>();
            update_by_info();
        }
        internal YacompPath CopyTo(YacompStorage storage)
        {
            return new YacompPath(info, storage);
        }
        public YacompPath ParentPath()
        {
            var path = helper.read_pathname(this.PathName.TrimEnd(helper.path_split_02));
            if (helper.is_root_path(path)) return ref_storage.root_path;
            return ref_storage.FindPath(path);
        }
        public bool IsRoot => this.root_path;
        internal void update_by_info()
        {
            PathName = helper.to_standard_path(info.pathname);
            if (PathName[0] == helper.path_split_02) PathName = PathName.Substring(1);
            Name = helper.read_pathname(PathName.TrimEnd(helper.path_split_02));

            var _pathname = PathName;
            if (_pathname[_pathname.Length - 1] != helper.path_split_02) _pathname += helper.path_split_02;
            info.path_bytes = helper.take_utf8_bytes(_pathname);
            info.path_bytes_size = (ushort)info.path_bytes.Length;
        }
        internal YacompPath(YacompStorage storage)
        {
            ref_storage = storage;
            root_path = true;
            files = new List<string>();
            paths = new List<string>();
        }

        internal void link_file(string file_hash)
        {
            if (ref_storage.file_map.ContainsKey(file_hash)) files.Add(file_hash);
        }
        internal void link_path(string path_hash)
        {
            if (ref_storage.path_map.ContainsKey(path_hash)) paths.Add(path_hash);
        }

        public IEnumerable<YacompPath> LoopPaths()
        {
            foreach (var hash in paths) if (ref_storage.exist_hash(hash)) yield return ref_storage.path_map[hash];
        }
        public IEnumerable<YacompFile> LoopFiles()
        {
            foreach (var hash in files) if (ref_storage.exist_hash(hash)) yield return ref_storage.file_map[hash];
        }
        public void Delete()
        {
            ref_storage.RemovePath(this.PathName);
        }

        internal void inner_dispose()
        {
            this.paths.Clear();
            this.files.Clear();
        }
    }
}
